package com.spa.domain.entity;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.ObjectUtil;
import com.spa.infrastructure.enums.dict.order.OrderStatusEnum;
import lombok.Data;

import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.Objects;

/**
 * 订单
 * 包含订单自己的属性、加钟订单的信息
 */
@Data
public class OrderInfo {

    /**
     * 
     */
    private Long id;

    /**
     * 订单编号
     */
    private String orderCode;

    /**
     * 用户ID
     */
    private Long userId;

    private UserInfo userInfo;
    /**
     * 用户名称
     */
    private String userName;

    /**
     * 用户手机号
     */
    private String userPhone;

    /**
     * 门店ID
     */
    private Long shopId;


    /**
     * 门店名称
     */
    private String shopName;

    /**
     * 门店手机号
     */
    private String shopPhone;

    /**
     * 项目ID
     */
    private Long serviceId;

    /**
     * 项目名称
     */
    private String serviceName;

    /**
     * 技师ID
     */
    private Long massagistId;

    /**
     * 技师名称
     */
    private String massagistName;

    /**
     * 技师手机号
     */
    private String massagistPhone;

    /**
     * 订单状态：
     * 10 未支付
     * 20 待接单
     * 30 进行中
     * 40 已完成
     * 99 已取消
     */
    private Integer status;

    /**
     * 是否转单 0否 1是
     */
    private Integer isTransfer;

    private Integer subStatus;

    /**
     * 订单操作状态 订单操作状态：31 已接单 32 已出发 33 已到达 34 服务中 35 服务完成
     */
    private Integer orderOperStatus;

    /**
     * 准确位置
     */
    private String exactLocation;

    /**
     * 来源
     */
    private String source;

    /**
     * 订单数量
     */
    private Integer orderCount;

    /**
     * 订单总金额
     */
    private Long totalAmount;

    /**
     * 订单金额，单位:分 (包含订单费用 + 出行费用)
     */
    private Integer orderPrice;

    /**
     * 出行费用金额，单位:分
     */
    private Integer travelPrice;

    /**
     * 出行距离
     */
    private String travelDist;

    /**
     * 出行方式
     */
    private String travelType;

    /**
     * 支付方式
     */
    private String priceType;

    /**
     * 支付时间
     */
    private Date payTime;

    /**
     * 预约时间
     */
    private Date appointTime;

    /**
     * 到期时间
     */
    private Date expiryTime;

    private OrderAddress orderAddress;

    /**
     * 技师到达时间
     */
    private Date arriveTime;

    /**
     * 技师出发时间
     */
    private Date departTime;

    /**
     * 技师接单时间
     */
    private Date takeTime;

    /**
     * 服务开始时间
     */
    private Date startTime;

    /**
     * 服务结束时间
     */
    private Date endTime;

    /**
     * 取消说明
     */
    private String cancelReason;

    /**
     * 取消时间
     */
    private Date cancelTime;

    /**
     * 订单备注
     */
    private String remark;

    /**
     * 是否有效 0 有效 1无效
     */
    private Integer isDel;

    /**
     * 创建人ID
     */
    private Long createBy;

    /**
     * 创建时间
     */
    private Date createTime;

    /**
     * 修改人ID
     */
    private Long updateBy;

    /**
     * 修改时间
     */
    private Date updateTime;


    /**
     * 加钟订单总金额
     */
    private Integer extTotalPrice;
    /**
     * 按此字段进行分组
     */
    private String date;

    /**
     * 按此字段进行分组
     */
    private int week;

    /**
     * 优惠券ID
     */
    private Long ticketId;


    /**
     * 服务总时长
     */
    private Integer durationSum;

    /**
     * 项目金额 显示为用户下单所选项目单价 * 数量
     */
    private Integer servicePrice;

    /**
     * 是否评价
     */
    private boolean hasComments;

    /**
     * 扩展字段1
     */
    private String extend1;

    /**
     * 扩展字段2
     */
    private String extend2;

    /**
     * 扩展字段3
     */
    private String extend3;

    /**
     * 扩展字段4
     */
    private String extend4;

    /**
     * 扩展字段5
     */
    private String extend5;

    private UserTicket ticket;

    private Shop shop;

    private MassageServiceEntity massageService;

    private Massagist massagist;

    /**
     * 加钟订单
     */
    private List<OrderExt> orderExtList;

    /**
     * 分润 分佣
     *
     * @author: lig
     * @date: 2024/2/27
     */
    private List<Profit> profitList;
    /**
     * 退款总金额
     *
     * @author: lig
     * @date: 2024/2/27
     */
    private Integer refundTotalMoney;

    /**
     * 订单总金额，单位:分 (包含订单费用 + 出行费用 + 加钟金额)
     * add  lig  2024-02-22
     */
    private Integer orderTotalPrice;

    /**
     * 技师提现ID
     */
    private Long massagistWithdrawId;

    /**
     * 门店提现ID
     */
    private Long shopWithdrawId;

    /**
     * 微信支付交易号
     */
    private String transactionId;

    private Trade trade;


    public Integer getExtTotalPrice() {
        if (CollectionUtil.isNotEmpty(orderExtList)) {
            return orderExtList.stream().map(OrderExt::getTotalPrice).reduce(Integer::sum).orElse(0);
        }
        return 0;
    }

    public Integer getDurationSum() {
        if (massageService != null) {
            return orderCount * massageService.getDuration();
        }
        return 0;
    }

    public Integer getServicePrice() {
        if (massageService != null) {
            return orderCount * massageService.getDiscountPrice();
        }
        return 0;
    }


    /**
     * 加钟统计
     *
     * @author: lig
     * @date: 2024/4/13
     */
    @Data
    public static class OrderExtCount {
        //加钟数量
        private Integer count = 0;
        //加钟率
        private Double ratio = 0.0;
        //加钟金额
        private Integer money = 0;

    }

    /**
     *  获取订单加钟统计信息
     *
     * @author: lig
     * @date: 2024/4/13
     */
    public static OrderExtCount gainOrderExtCount(List<OrderInfo> orderInfos) {
        OrderExtCount massagistOrderExtCount = new OrderExtCount();
        //已完成订单
        List<OrderInfo> complete = orderInfos.stream().filter(o1 -> Objects.equals(o1.getStatus(), OrderStatusEnum.$40.getCode())).toList();
        if (CollUtil.isEmpty(complete)) {
            return massagistOrderExtCount;
        }
        List<OrderExt> orderExts = complete.stream().map(OrderInfo::getOrderExtList).filter(CollectionUtil::isNotEmpty).flatMap(Collection::stream).toList();
        if (CollUtil.isEmpty(orderExts)) {
            return massagistOrderExtCount;
        }

        //加钟金额
        Integer extMoney = orderExts.stream().map(OrderExt::getOrderPrice).filter(ObjectUtil::isNotNull).reduce(0, Integer::sum);
        //加钟数量
        int extCount = orderExts.stream().mapToInt(OrderExt::getOrderCount).sum();
        //技师规则 - 指标 - 加钟率
        Double extraRatio = NumberUtil.round(NumberUtil.div(extCount, complete.size()),2).doubleValue();

        massagistOrderExtCount.setMoney(extMoney);
        massagistOrderExtCount.setCount(Convert.toInt(extCount, 0));
        massagistOrderExtCount.setRatio(Convert.toDouble(extraRatio, 0d));
        return massagistOrderExtCount;
    }

}